#include "BlockQueue.hpp"
#include "Task.hpp"
#include <iostream>

// 任务1
// template <class T>
// void* Comsume(void* arg){
// 	BlockQueue<T>* bq = static_cast<BlockQueue<T>*>(arg);
// 	while(true){
// 		T task = bq->Pop();
// 		int ret = task.Result();
// 		std::cout << "x + y = : " << ret << std::endl;
// 		sleep(1);
// 	}

// 	return nullptr;
// }

// template <class T>
// void* Produce(void* arg){
// 	BlockQueue<T>* bq = static_cast<BlockQueue<T>*>(arg);
// 	int x = 10;
// 	int y = 20;
// 	while(true){
// 		Task t(x, y);
// 		t.Execute();
// 		bq->Equeue(t);
// 		std::cout << "x + y =: ?" << std::endl;
// 		x++, y++;
// 		sleep(1);
// 	}

// 	return nullptr;
// }

// int main()
// {
// 	BlockQueue<Task>* bq = new BlockQueue<Task>();
// 	pthread_t comsumer, producer;
// 	pthread_create(&comsumer, nullptr, Comsume<Task>, bq);
// 	pthread_create(&producer, nullptr, Produce<Task>, bq);

// 	pthread_join(comsumer, nullptr);
// 	pthread_join(producer, nullptr);

// 	return 0;
// }

//任务2
template <class T>
void* Comsume(void* arg){
	BlockQueue<T>* bq = static_cast<BlockQueue<T>*>(arg);
	while(true){
		T task = bq->Pop();
		sleep(2);
		task();
	}

	return nullptr;
}

template <class T>
void* Produce(void* arg){
	BlockQueue<T>* bq = static_cast<BlockQueue<T>*>(arg);
	while(true){
		std::cout<<"生产了一个任务..."<<std::endl;
		bq->Equeue([](){
			Download();
		});
		sleep(2);
	}

	return nullptr;
}

int main()
{
	BlockQueue<task_t>* bq = new BlockQueue<task_t>();
	pthread_t comsumer[2], producer[3];
	pthread_create(&comsumer[0], nullptr, Comsume<task_t>, bq);
	pthread_create(&comsumer[1], nullptr, Comsume<task_t>, bq);
	pthread_create(&producer[0], nullptr, Produce<task_t>, bq);
	pthread_create(&producer[1], nullptr, Produce<task_t>, bq);
	pthread_create(&producer[2], nullptr, Produce<task_t>, bq);

	pthread_join(comsumer[0], nullptr);
	pthread_join(comsumer[1], nullptr);
	pthread_join(producer[0], nullptr);
	pthread_join(producer[1], nullptr);
	pthread_join(producer[2], nullptr);

	return 0;
}